home *** CD-ROM | disk | FTP | other *** search
- Subject: v19i012: A command-line editor (for BSD), Part03/04
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: ka@june.cs.washington.edu (Kenneth Almquist)
- Posting-number: Volume 19, Issue 12
- Archive-name: atty/part03
-
- # This is part 3 of atty. To unpack, feed it into the shell (not csh).
- # The atty distribution consists of four pieces. After you unpack everyting,
- # read the file README.
-
- echo extracting kbind.c
- cat > kbind.c <<\EOF
- /*
- * The kbind program - compile .bind files.
- *
- * Copyright (C) 1989 by Kenneth Almquist. All rights reserved.
- * This file is part of atty, which is distributed under the terms specified
- * by the Atty General Public License. See the file named LICENSE.
- */
-
- #include <stdio.h>
- #include "bind.h"
-
-
- #define VERSION 21 /* change if you change the .bindc format */
-
-
- /*
- * List of commands.
- */
-
- char *command[] = {
- "universal-argument",
- "digit-argument",
- "negative-argument",
- "self-insert",
- "quoted-insert",
- "newline",
- "end-of-file",
- "eof-or-delete-char",
- "newline-and-insert",
- "tty-intr",
- "tty-quit",
- "tty-susp",
- "delete-backward-char",
- "delete-char",
- "kill-word",
- "backward-kill-word",
- "kill-region",
- "kill-line",
- "kill-input",
- "copy-region-as-kill",
- "forward-char",
- "backward-char",
- "forward-word",
- "backward-word",
- "beginning-of-line",
- "end-of-line",
- "yank",
- "set-mark",
- "exchange-point-and-mark",
- "upcase-char",
- "upcase-word",
- "upcase-region",
- "gosling-transpose-chars",
- "transpose-chars",
- "transpose-words",
- "next-history",
- "previous-history",
- "beginning-of-history",
- "end-of-history",
- "re-search-forward",
- "re-search-backward",
- "file-complete",
- "list-file-completions",
- "get-history-word",
- "last-output-line",
- "mode-0",
- "mode-1",
- 0
- };
-
-
-
- /* Token types */
- #define TWORD 1 /* generic word */
- #define TNL 2 /* newline */
- #define TSTRING 3 /* quoted string */
-
-
- #define C_UNSET 127 /* command is not set */
-
-
- #define NMODES 2 /* maximum number of modes */
- #define TBLSIZE 128 /* size of a key table */
- #define MAXTBL 32 /* maximum number of key tables */
- #define STRINGSPACE 5000 /* space for holding strings */
- #define MAXABBREV 500 /* maximum number of abbreviations */
-
-
- struct cmd {
- unsigned char type; /* type of command */
- unsigned char index; /* which command */
- int linno; /* line where defined */
- };
-
-
- struct mode {
- int used; /* set if mode is in use */
- struct cmd dft; /* default binding */
- struct cmd *keytab; /* base key table for this mode */
- };
-
-
- struct syntax {
- char *name; /* name of this syntax class */
- int defined; /* set if syntax defined */
- char bitmap[16]; /* bit map specifying which characters are
- in the class */
- };
-
-
- struct abbrev {
- int fromlen; /* length of "from" */
- char *from; /* the abbreviation */
- int tolen; /* length of "to" */
- char *to; /* what it is defined as */
- };
-
-
- char *inputfile; /* name of input file */
- FILE *infp; /* input file */
- char outputfile[1024]; /* name of output file */
- FILE *outfp; /* output file */
- struct mode mode[NMODES]; /* modes */
- struct mode *curmode; /* current mode */
- int nmodes; /* number of modes actually used */
- struct cmd *keytab[MAXTBL]; /* key binding tables */
- int nkeytab; /* number of key tables */
- struct syntax syntax[NSYNTAX]; /* syntax tables */
- char stringspace[STRINGSPACE]; /* space for holding strings */
- char *strnext; /* next entry in string table */
- int nstrings; /* number of strings in string table */
- int nabbrev; /* number of abbreviations */
- struct abbrev abbrev[MAXABBREV];/* abbreviations */
- int abbrevsize; /* total size of abbreviation table */
- int mode_1_line; /* line that mode-1 command occured on */
- int lasttoken; /* type of last token read */
- int tokpushback; /* set to push back token */
- char toktext[1024]; /* text of last token read */
- char tokstring[512]; /* input string */
- char stringlen; /* length of tokstring */
- int linno; /* current line of input */
- int nerrors; /* number of errors encountered */
- int debug; /* set for debugging info */
-
-
- #ifdef __STDC__
- void makefuncs(void);
- char *cname(char *);
- void parsefile(void);
- void parseline(void);
- void parsecmd(struct cmd *);
- void setmode(int);
- void bind(char *, int, struct cmd *);
- struct cmd *newkeytab(void);
- void defaultbind(void);
- void setdftbind(struct cmd *, struct cmd *);
- void setsyntax(char *, char *, int);
- void chknl(void);
- int gettoken(void);
- int getstring(void);
- void cvttext(int);
- int ateof(void);
- char *saveblock(char *, int);
- void error(char *);
- int writeout(void);
- void putkeytab(struct cmd *);
- void putsh(int, FILE *);
- #else
- void makefuncs();
- char *cname();
- void parsefile();
- void parseline();
- void parsecmd();
- void setmode();
- void bind();
- struct cmd *newkeytab();
- void defaultbind();
- void setdftbind();
- void setsyntax();
- void chknl();
- int gettoken();
- int getstring();
- void cvttext();
- int ateof();
- char *saveblock();
- void error();
- int writeout();
- void putkeytab();
- void putsh();
- #endif
-
- char *malloc();
- #define equal(s1, s2) (strcmp(s1, s2) == 0)
-
-
-
- main(argc, argv)
- char **argv;
- {
- char **ap;
- int status;
-
- if (argc <= 1) {
- fputs("Usage: kbind file.bind ...\n", stderr);
- exit(2);
- }
- if (argc == 2 && equal(argv[1], "-makefuncs")) {
- makefuncs();
- return 0;
- }
- if (equal(argv[1], "-d")) {
- argv++;
- debug = 1;
- }
- status = 0;
- for (ap = argv + 1 ; *ap ; ap++) {
- inputfile = *ap;
- if ((infp = fopen(inputfile, "r")) == NULL) {
- fprintf(stderr, "Can't open %s\n", inputfile);
- status = 2;
- }
- nerrors = 0;
- parsefile();
- if (nerrors != 0) {
- if (status == 0)
- status = 1;
- continue;
- }
- if (writeout() < 0)
- status = 2;
- }
- exit(status);
- }
-
-
- /*
- * Generate function index to be compiled with atty.
- */
-
- char head[] = "\
- /*\n\
- * This file was created by the kbind program.\n\
- */\n\
- \n";
-
- void
- makefuncs() {
- char **pp;
-
- if ((outfp = fopen("edfuncs.c", "w")) == NULL) {
- fputs("Can't create edfuncs.c\n", stderr);
- exit(2);
- }
- fputs(head, outfp);
- for (pp = command ; *pp ; pp++) {
- fprintf(outfp, "int %s();\n", cname(*pp));
- }
- putc('\n', outfp);
- fputs("int (*edfunc[])() = {\n", outfp);
- for (pp = command ; *pp ; pp++) {
- fprintf(outfp, " %s,\n", cname(*pp));
- }
- fputs("};\n\n", outfp);
- fprintf(outfp, "int version = %d;\n", VERSION);
- }
-
-
- /*
- * Convert a function name to the way that it appears in C.
- */
-
- char *
- cname(s)
- char *s;
- {
- static char buf[128];
- char *p;
-
- strcpy(buf, s);
- for (p = buf ; *p ; p++) {
- if (*p == '-')
- *p = '_';
- }
- return buf;
- }
-
-
- void
- parsefile() {
- int i;
-
- linno = 1;
- curmode = NULL;
- nkeytab = 0;
- nmodes = 0;
- strnext = stringspace;
- nstrings = 0;
- nabbrev = 0;
- syntax[0].name = "word";
- syntax[0].defined = 0;
- syntax[1].name = "filename";
- syntax[1].defined = 0;
- syntax[2].name = "abbrev";
- syntax[2].defined = 0;
- for (i = 0 ; i < NMODES ; i++) {
- mode[i].used = 0;
- mode[i].dft.type = C_UNSET;
- mode[i]. keytab = NULL;
- }
-
- while (! ateof()) {
- parseline();
- }
- for (i = 0 ; i < NSYNTAX ; i++) {
- if (! syntax[i].defined)
- setsyntax(syntax[i].bitmap, "^ \t", 3);
- }
- if (curmode == NULL) {
- printf("%s:%d: No bindings specified\n", inputfile, linno);
- nerrors++;
- } else if (mode[0].used == 0) {
- printf("%s:%d: Mode zero not defined\n", inputfile, linno);
- nerrors++;
- }
- if (mode_1_line != 0 && mode[1].used == 0) {
- printf("%s:%d: Mode 1 referenced (line %d), but never defined\n",
- inputfile, linno, mode_1_line);
- nerrors++;
- }
- nmodes = 1;
- for (i = 1 ; i < NMODES ; i++) {
- if (mode[i].used) {
- if (! mode[i - 1].used) {
- printf("%s:%d: Mode %d is defined, but mode %d is not\n",
- inputfile, linno, i, i - 1);
- nerrors++;
- }
- nmodes = i + 1;
- }
- }
- defaultbind();
- abbrevsize = 0;
- for (i = 0 ; i < nabbrev ; i++) {
- abbrevsize += abbrev[i].fromlen + abbrev[i].tolen + 2;
- }
- }
-
-
-
- void
- parseline() {
- struct cmd cmd;
- char binding[128];
- int bindlen;
- int i;
-
- if (gettoken() == TNL)
- goto out;
- if (lasttoken != TWORD) {
- error("Expecting command");
- goto out;
- }
- if (toktext[0] == '#') {
- /* a comment, ignore it */
- } else if (equal(toktext, "b")) {
- if (curmode == NULL) {
- error("No mode specified");
- setmode(0);
- }
- if (gettoken() != TWORD) {
- error("Expecting key sequence for b command");
- goto out;
- }
- cvttext(1); /* parse and save value */
- bindlen = stringlen;
- bcopy(tokstring, binding, bindlen);
- parsecmd(&cmd);
- bind(binding, bindlen, &cmd);
- chknl();
- } else if (equal(toktext, "mode")) {
- if (gettoken() != TWORD || *toktext < '0'
- || *toktext > '9' || toktext[1] != '\0') {
- error("Expecting mode number");
- goto out;
- }
- setmode(atoi(toktext));
- chknl();
- } else if (equal(toktext, "default")) {
- if (curmode == NULL) {
- error("No mode specified");
- setmode(0);
- }
- parsecmd(&cmd);
- curmode->dft = cmd;
- chknl();
- } else if (equal(toktext, "syntax")) {
- if (gettoken() != TWORD) {
- error("Expecting syntax class name");
- goto out;
- }
- for (i = 0 ; ; i++) {
- if (equal(toktext, syntax[i].name))
- break;
- if (i == NSYNTAX - 1)
- error("Unimplemented syntax class");
- }
- if (syntax[i].defined)
- error("Redefining syntax class");
- if (getstring() < 0)
- goto out;
- cvttext(0);
- setsyntax(syntax[i].bitmap, tokstring, stringlen);
- syntax[i].defined = 1;
- chknl();
- } else if (equal(toktext, "abbrev")) {
- if (nabbrev >= MAXABBREV) {
- error("Too many abbreviations");
- nabbrev = 0;
- }
- if (getstring() < 0)
- goto out;
- cvttext(0);
- if (stringlen == 0)
- error("Can't define the null string to be an abbreviation");
- abbrev[nabbrev].fromlen = stringlen;
- abbrev[nabbrev].from = saveblock(tokstring, stringlen);
- if (getstring() < 0)
- goto out;
- cvttext(0);
- abbrev[nabbrev].tolen = stringlen;
- abbrev[nabbrev].to = saveblock(tokstring, stringlen);
- nabbrev++;
- chknl();
- } else {
- error("Unrecognized command");
- }
- out:
- while (lasttoken != TNL)
- gettoken();
- }
-
-
- void
- parsecmd(cmdp)
- struct cmd *cmdp;
- {
- char **pp;
-
- cmdp->type = C_UNDEF;
- cmdp->linno = linno;
- if (gettoken() != TWORD) {
- error("Expecting function name");
- return;
- }
- if (equal(toktext, "insert")) {
- if (getstring() < 0)
- return;
- if (nstrings >= 255) {
- error("Too many strings");
- return;
- }
- cvttext(0);
- if ((strnext - stringspace) + 1 + stringlen > STRINGSPACE) {
- error("Out of space for string constants");
- return;
- }
- *strnext++ = stringlen;
- bcopy(tokstring, strnext, stringlen);
- strnext += stringlen;
- cmdp->type = C_INSERT;
- cmdp->index = nstrings++;
- } else if (equal(toktext, "undefined")) {
- cmdp->type = C_UNDEF;
- cmdp->index = 0;
- } else {
- for (pp = command ; *pp && ! equal(*pp, toktext) ; pp++);
- if (*pp == NULL) {
- error("Unrecognized function");
- return;
- }
- if (equal(toktext, "mode-1"))
- mode_1_line = linno;
- cmdp->type = C_FUNC;
- cmdp->index = pp - command;
- }
- }
-
-
- void
- setmode(modenum) {
- if (modenum < 0 || modenum >= NMODES) {
- error("Mode number out of range");
- return;
- }
- curmode = &mode[modenum];
- curmode->used = 1;
- if (curmode->keytab == NULL)
- curmode->keytab = newkeytab();
- }
-
-
- void
- bind(keyseq, seqlen, cmdp)
- char *keyseq;
- int seqlen;
- struct cmd *cmdp;
- {
- struct cmd *k;
- struct cmd *cp;
- char *p;
- int lno;
-
- if (seqlen == 0) { /* can't happen */
- error("Empty binding sequence");
- return;
- }
- if (curmode == NULL) { /* can't happen */
- error("No current mode");
- setmode(0);
- }
- k = curmode->keytab;
- p = keyseq;
- while (--seqlen > 0) {
- cp = &k[*p++ & 0177];
- if (cp->type == C_UNSET) {
- if (nkeytab >= MAXTBL) {
- error("Too many key tables required");
- return;
- }
- keytab[nkeytab++] = k = newkeytab();;
- cp->type = C_PFXTBL;
- cp->index = nkeytab - 1;
- cp->linno = cmdp->linno;
- } else if (cp->type == C_PFXTBL) {
- k = keytab[cp->index];
- } else {
- goto redef;
- }
- }
- cp = &k[*p & 0177];
- if (cp->type != C_UNSET) {
- redef:
- printf("%s:%d: Redefining key. (Initial definition line %d)\n",
- inputfile, cmdp->linno, cp->linno);
- nerrors++;
- return;
- }
- *cp = *cmdp;
- }
-
-
- /*
- * Create a new key table.
- */
-
- struct cmd *
- newkeytab() {
- struct cmd *keytab;
- struct cmd *p;
-
- if ((keytab = (struct cmd *)malloc(TBLSIZE * sizeof *keytab)) == NULL) {
- error("Out of space");
- exit(2);
- }
- p = keytab + TBLSIZE;
- do {
- (--p)->type = C_UNSET;
- } while (p > keytab);
- return keytab;
- }
-
-
- /*
- * Set the default bindings.
- */
-
- void
- defaultbind() {
- int tabno;
- struct cmd *cp;
- int i;
- static struct cmd dft = {C_UNDEF, 0, 0};
-
- for (tabno = 0 ; tabno < nmodes ; tabno++) {
- if (mode[tabno].dft.type == C_UNSET)
- setdftbind(mode[tabno].keytab, &dft);
- else
- setdftbind(mode[tabno].keytab, &mode[tabno].dft);
- }
- for (tabno = 0 ; tabno < nkeytab ; tabno++) {
- setdftbind(keytab[tabno], &dft);
- }
- }
-
-
-
- void
- setdftbind(tab, dft)
- struct cmd *tab;
- struct cmd *dft;
- {
- struct cmd *cp;
- int i;
-
- for (i = 128, cp = tab ; --i >= 0 ; cp++) {
- if (cp->type == C_UNSET)
- *cp = *dft;
- }
- }
-
-
-
- /*
- * Set up a syntax table.
- */
-
- void
- setsyntax(table, string, len)
- char table[16];
- char *string;
- {
- register char *p;
- int c;
- int invert;
-
- for (p = table ; p < table + 16 ; p++)
- *p = 0;
- p = string;
- invert = 0;
- if (len > 0 && *p == '^') {
- len--;
- p++;
- invert++;
- }
- while (--len >= 0) {
- if (len >= 2 && p[1] == '-') {
- for (c = p[0] ; c <= p[2] ; c++) {
- table[(c & 0177) >> 3] |= 1 << (c & 07);
- }
- p += 3;
- len -= 2;
- } else {
- c = *p++;
- table[(c & 0177) >> 3] |= 1 << (c & 07);
- }
- }
- if (invert) {
- for (p = table ; p < table + 16 ; p++)
- *p = ~*p;
- }
- }
-
-
- /*
- * Be sure the next token is a newline.
- */
-
- void
- chknl() {
- if (gettoken() != TNL)
- error("Expecting NEWLINE");
- }
-
-
- /*
- * Return the next input token.
- */
-
- int
- gettoken() {
- int c;
- char *p;
-
- if (tokpushback) {
- tokpushback = 0;
- return lasttoken;
- }
- lasttoken = 0;
- while ((c = getc(infp)) == ' ' || c == '\t');
- if (c == '\n') {
- linno++;
- return lasttoken = TNL;
- }
- p = toktext;
- do {
- if (c == EOF) {
- *p = '\0';
- error("EOF in middle of line");
- exit(2);
- }
- if (p >= toktext + sizeof toktext - 2) {
- *p = '\0';
- error("Input token too long");
- p = toktext;
- }
- *p++ = c;
- } while ((c = getc(infp)) != ' ' && c != '\t' && c != '\n');
- ungetc(c, infp);
- *p = '\0';
- return lasttoken = TWORD;
- }
-
-
-
- /*
- * Parse a string.
- */
-
- int
- getstring() {
- int c;
- char *p;
-
- toktext[0] = '\0';
- lasttoken = 0;
- while ((c = getc(infp)) == ' ' || c == '\t');
- if (c == EOF) {
- error("EOF in middle of line");
- exit(2);
- }
- if (c != '"') {
- ungetc(c, infp);
- gettoken();
- error("Expecting a quoted string");
- return -1;
- }
- p = toktext;
- for (;;) {
- c = getc(infp);
- if (c == '"')
- break;
- if (c == '\\') {
- *p++ = c;
- c = getc(infp);
- }
- if (c == EOF) {
- *p = '\0';
- error("EOF in middle of line");
- exit(2);
- }
- if (c == '\n') {
- ungetc(c, infp);
- error("Unterminated string");
- return -1;
- }
- if (p >= toktext + sizeof toktext - 2) {
- *p = '\0';
- error("String too long");
- p = toktext;
- }
- *p++ = c;
- }
- *p = '\0';
- lasttoken = TSTRING;
- }
-
-
- /*
- * Parse the text in the last token string.
- */
-
-
- void
- cvttext(doctl) {
- register char *p, *q;
- char *endp = toktext + strlen(toktext);
- int n;
- int c;
-
- q = tokstring;
- for (p = toktext ; p < endp ; p++) {
- if (q >= tokstring + 127) {
- error("String exceeds 127 characters");
- break;
- }
- if (*p == '\\') {
- switch (*++p) {
- case 'b': *q++ = '\b'; break;
- case 'e': *q++ = '\033'; break; /* escape */
- case 'f': *q++ = '\f'; break;
- case 'n': *q++ = '\n'; break;
- case 'r': *q++ = '\r'; break;
- case 's': *q++ = ' '; break;
- case 't': *q++ = '\t'; break;
- case '0': case '1': case '2': case '3':
- case '4': case '5': case '6': case '7':
- c = *p - '0';
- n = 3;
- while (*++p >= '0' && *p <= '7' && --n > 0) {
- c = (c << 3) + *p - '0';
- }
- *q++ = c;
- break;
- default:
- *q++ = *p;
- break;
- }
- } else if (*p == '^' && doctl) {
- if (*++p == '?')
- *q++ = '\177';
- else
- *q++ = *p & 037;
- } else {
- *q++ = *p;
- }
- }
- stringlen = q - tokstring;
- }
-
-
- int
- ateof() {
- int c;
-
- if (feof(infp) || (c = getc(infp)) == EOF)
- return 1;
- ungetc(c, infp);
- return 0;
- }
-
-
- char *
- saveblock(block, len)
- char *block;
- int len;
- {
- char *p;
-
- if ((p = malloc(len)) == NULL) {
- error("Out of space");
- exit(2);
- }
- bcopy(block, p, len);
- return p;
- }
-
-
- void
- error(msg)
- char *msg;
- {
- int lno;
- static int lasterror = -1;
-
- lno = (lasttoken == TNL)? linno - 1 : linno;
- if (lno != lasterror) {
- lasterror = lno;
- printf("%s:%d: %s", inputfile, lno, msg);
- if (lasttoken == TNL)
- printf(" (input token = NEWLINE)\n");
- else
- printf(" (input token = \"%s\")\n", toktext);
- }
- nerrors++;
- }
-
-
- int
- writeout() {
- int i;
- int tabno;
- int stringno;
- int stringloc;
- struct abbrev *ap;
-
- if (debug)
- return dbwriteout();
- strcpy(outputfile, inputfile);
- if ((i = strlen(inputfile)) < 5 || ! equal(inputfile + i - 5, ".bind"))
- strcat(outputfile, ".bindc");
- else
- strcat(outputfile, "c");
- if ((outfp = fopen(outputfile, "w")) == NULL) {
- fprintf(stderr, "Can't create %s\n", outputfile);
- return -1;
- }
- putsh(BINDMAGIC, outfp);
- putc(VERSION, outfp);
- putc(nmodes + nkeytab, outfp);
- putsh(strnext - stringspace, outfp);
- putsh(abbrevsize, outfp);
- for (tabno = 0 ; tabno < nmodes ; tabno++) {
- putkeytab(mode[tabno].keytab);
- }
- for (tabno = 0 ; tabno < nkeytab ; tabno++) {
- putkeytab(keytab[tabno]);
- }
- for (i = 0 ; i < NSYNTAX ; i++)
- fwrite(syntax[i].bitmap, sizeof syntax[i].bitmap, 1, outfp);
- fwrite(stringspace, strnext - stringspace, 1, outfp);
- for (i = 0, ap = abbrev ; i < nabbrev ; i++, ap++) {
- putc(ap->fromlen, outfp); abbrevsize -= 1;
- fwrite(ap->from, ap->fromlen, 1, outfp); abbrevsize -= ap->fromlen;
- putc(ap->tolen, outfp); abbrevsize -= 1;
- fwrite(ap->to, ap->tolen, 1, outfp); abbrevsize -= ap->tolen;
- }
- if (abbrevsize != 0)
- abort();
- if (ferror(outfp) || fclose(outfp) == EOF) {
- fprintf(stderr, "Write error on %s\n", outputfile);
- return -1;
- }
- return 0;
- }
-
-
- void
- putkeytab(tab)
- struct cmd *tab;
- {
- struct cmd *cp;
- int ch;
-
- cp = tab;
- for (ch = 0 ; ch <= 127 ; ch++) {
- putc(cp->type, outfp);
- cp++;
- }
- cp = tab;
- for (ch = 0 ; ch <= 127 ; ch++) {
- if (cp->type == C_PFXTBL)
- putc(cp->index + nmodes, outfp);
- else
- putc(cp->index, outfp);
- cp++;
- }
- }
-
-
- void
- putsh(i, fp)
- FILE *fp;
- {
- putc(i, fp);
- putc(i >> 8, fp);
- }
-
-
- #if 1
- int
- dbwriteout() {
- int i;
- int tabno;
- int stringno;
- int stringloc;
- struct abbrev *ap;
- char *p;
-
- strcpy(outputfile, inputfile);
- if ((i = strlen(inputfile)) < 5 || ! equal(inputfile + i - 5, ".bind"))
- strcat(outputfile, ".bindc");
- else
- strcat(outputfile, "c");
- if ((outfp = fopen(outputfile, "w")) == NULL) {
- fprintf(stderr, "Can't create %s\n", outputfile);
- return -1;
- }
- for (tabno = 0 ; tabno < nmodes ; tabno++) {
- fprintf(outfp, "keytab for mode %d:\n", tabno);
- dbputkeytab(mode[tabno].keytab);
- }
- for (tabno = 0 ; tabno < nkeytab ; tabno++) {
- fprintf(outfp, "keytab %d:\n", tabno + nmodes);
- dbputkeytab(keytab[tabno]);
- }
- for (i = 0 ; i < NSYNTAX ; i++)
- dbputsyntax(syntax[i].name, syntax[i].bitmap);
- fprintf(outfp, "\nstrings:\n");
- stringloc = 0;
- for (stringno = 0 ; stringno < nstrings ; stringno++) {
- fprintf(outfp, "%-4d ", i = stringspace[stringloc++]);
- while (--i >= 0)
- outchar(stringspace[stringloc++]);
- putc('\n', outfp);
- }
- fprintf(outfp, "\nAbbreviations:\n");
- for (stringno = 0, ap = abbrev ; stringno < nabbrev ; stringno++, ap++) {
- i = ap->fromlen, p = ap->from;
- while (--i >= 0)
- outchar(*p++);
- fputs(": ", outfp);
- i = ap->tolen, p = ap->to;
- while (--i >= 0)
- outchar(*p++);
- putc('\n', outfp);
- abbrevsize -= ap->fromlen + ap->tolen + 2;
- }
- if (abbrevsize != 0)
- abort();
- }
-
-
-
- dbputkeytab(tab)
- struct cmd *tab;
- {
- struct cmd *cp;
- int ch;
-
- cp = tab;
- for (ch = 0 ; ch <= 127 ; ch++) {
- outchar1(ch);
- putc(' ', outfp);
- if (cp->type == C_FUNC) {
- fprintf(outfp, "%s\n", command[cp->index]);
- } else if (cp->type == C_PFXTBL) {
- fprintf(outfp, "keytab %d\n", cp->index + nmodes);
- } else if (cp->type == C_INSERT) {
- fprintf(outfp, "insert %d\n", cp->index);
- } else if (cp->type == C_UNDEF) {
- fprintf(outfp, "<undef>\n");
- } else if (cp->type == C_UNSET) {
- fprintf(outfp, "{}\n");
- } else {
- fprintf(outfp, "type = %d, index = %d\n", cp->type, cp->index);
- }
- cp++;
- }
- putc('\n', outfp);
-
- }
-
-
-
- dbputsyntax(name, syntax)
- char *name;
- char *syntax;
- {
- int c;
- int start;
-
- fprintf(outfp, "%s syntax: ", name);
- start = -1;
- for (c = 0 ; c <= 128 ; c++) {
- if (c != 128 && syntax[c >> 3] & 1 << (c & 07)) {
- if (start < 0) {
- start = c;
- }
- } else {
- if (start >= 0) {
- outchar(start);
- if (start != c - 1) {
- putc('-', outfp);
- outchar(c - 1);
- }
- start = -1;
- }
- }
- }
- putc('\n', outfp);
- }
-
-
-
- outchar1(ch) {
- if (ch < ' ')
- fprintf(outfp, "^%c", ch ^ 0100);
- else if (ch == ' ')
- fprintf(outfp, "SP");
- else if (ch == '\177')
- fprintf(outfp, "^?");
- else
- fprintf(outfp, "%c ", ch);
- }
-
-
-
- outchar(ch) {
- if (ch < ' ')
- fprintf(outfp, "^%c", ch ^ 0100);
- else if (ch == '\177')
- fprintf(outfp, "^?");
- else
- putc(ch, outfp);
- }
- #endif
- EOF
- if test `wc -c < kbind.c` -ne 23061
- then echo 'kbind.c is the wrong size'
- fi
- echo extracting makefile
- cat > makefile <<\EOF
- # Copyright (C) 1989 by Kenneth Almquist.
-
- FILES=atty.o output.o ed.o edfuncs.o update.o dftbind.o regex.o
-
- #CC=gcc
- DEBUG=-g
- CFLAGS=$(DEBUG)
- LIBS=-ltermcap
- #P=& # for Sequent's parallel make
-
- all:$P kbind atty fmatch atty.1 atty.bindc
-
- clean:
- rm -f *.o
-
- clobber:
- rm -f *.o atty kbind fmatch edfuncs.c dftbind.c atty.1 atty.bindc
-
- atty:$P $(FILES)
- $(CC) -o temp $(FILES) $(LIBS)
- mv -f temp $@
-
- kbind: kbind.o
- $(CC) -o $@ kbind.o
-
- edfuncs.c: kbind
- ./kbind -makefuncs
-
- dftbind.c:
- echo "char dftbind[] = \"`pwd`/atty.bindc\";" > $@
-
- atty.bindc: atty.bind kbind
- ./kbind atty.bind
-
- fmatch: fmatch.o
- $(CC) -g -o $@ fmatch.o
-
- atty.1: atty.1.mk
- sh atty.1.mk > atty.1
-
- atty.o: atty.h attyed.h
- ed.o: attyed.h ed.h bind.h regex.h
- kbind.o: bind.h
- output.o: atty.h attyed.h
- update.o: attyed.h ed.h
- EOF
- if test `wc -c < makefile` -ne 794
- then echo 'makefile is the wrong size'
- fi
- echo extracting output.c
- cat > output.c <<\EOF
- /*
- * Copyright (C) 1989 by Kenneth Almquist.
- */
-
- #include <stdio.h>
- #include <sgtty.h> /* for atty.h */
- #include "atty.h"
- #include "attyed.h"
-
-
-
- int outstate;
- int column;
- char outline[COLUMNS];
- char prompt[COLUMNS];
- int promptlen;
- int param[2];
- char strparam[256];
- int nparam;
- char *strparamp;
- char esccmd;
- int *curnumber;
- int promptcode;
- int promptset;
- char lastoutline[COLUMNS];
- int lastoutlinelen;
-
-
- /*
- * All output passes through the outchars routine. The routine keeps
- * track of the current column and identifies escape sequences that
- * are interpreted by atty itself.
- */
-
- outchars(p, n)
- char *p;
- int n;
- {
- char c;
- int newcol;
- int i;
- char *savep;
- char *q;
- int savecol = column;
-
- savep = p;
- switch (outstate) {
- case 0:
- state0: /* base state */
- while (--n >= 0) {
- c = *p++;
- if (c >= ' ' && c <= '~') {
- if (column < COLUMNS)
- outline[column] = c;
- column++;
- } else if (c == '\t') {
- newcol = (column + 8) &~ 07;
- while (column < newcol && column < COLUMNS)
- outline[column++] = ' ';
- column = newcol;
- } else if (c == '\r') {
- if ((lastoutlinelen = column) > COLUMNS)
- lastoutlinelen = COLUMNS;
- bcopy(outline, lastoutline, lastoutlinelen);
- column = 0;
- } else if (c == '\033') { /* ESCAPE */
- outstate = 1;
- goto state1;
- } else if (c == '\b') {
- if (column > 0)
- column--;
- }
- }
- break;
- case 1:
- state1: /* escape character seen */
- if (--n < 0)
- break;
- c = *p++;
- if (c == '[') {
- outstate = 2;
- nparam = 0;
- param[0] = param[1] = 0;
- curnumber = NULL;
- goto state2;
- } else if (c == ']') {
- if (p - 2 > savep) {
- dispoff(savecol);
- outreal(savep, p - 2 - savep);
- }
- outstate = 3;
- goto state3;
- } else if (c == 'H') { /* ESC H = home on some terminals */
- column = 0;
- outstate = 0;
- goto state0;
- } else {
- outstate = 0;
- goto state0;
- }
- case 2:
- state2: /* ESC [ seen */
- while (--n >= 0) {
- c = *p++;
- if (c >= '0' && c <= '9') {
- if (curnumber != NULL) {
- *curnumber = *curnumber * 10 + c - '0';
- } else if (nparam < 2) {
- curnumber = ¶m[nparam++];
- *curnumber = c - '0';
- }
- } else if (c == '?') {
- /* ignore it for now */
- } else if (c == ';') {
- curnumber = NULL;
- } else {
- goto gotescape;
- }
- }
- break;
-
- gotescape:
- /* got a complete escape sequence */
- switch (c) {
- case 'H':
- column = param[1] > 0? param[1] - 1 : 0;
- break;
- case 'C':
- column += param[0];
- break;
- case 'D':
- if ((column -= param[0]) < 0)
- column = 0;
- break;
- case 'L': case'M':
- column = 0;
- break;
- case 'J':
- if (param[0] == 1 || param[0] == 2) {
- for (i = 0 ; i < column && i < COLUMNS; i++)
- outline[i] = ' ';
- }
- break;
- }
- outstate = 0;
- goto state0;
- case 3:
- state3: /* got ESC ], which introduces an atty control sequence */
- if (--n < 0)
- break;
- c = *p++;
- if (c == 'P' || c == 'I' || c == 'D') {
- esccmd = c;
- strparamp = strparam;
- outstate = 4;
- goto state4;
- } else {
- dispoff(savecol);
- ttyoutc('\033');
- ttyoutc(']');
- ttyoutc(c);
- savep = p - 1;
- outstate = 0;
- goto state0;
- }
- break;
- case 4:
- state4: /* reading prompt following ESC ] P */
- while (--n >= 0) {
- c = *p++;
- if (c == '\n') {
- *strparamp = '\0';
- goto myesc;
- }
- if (c != '\r' && strparamp < &strparam[255]) {
- *strparamp++ = c;
- }
- }
- break;
-
- myesc:
- /* got an ESC ] ... sequence */
- switch (esccmd) {
- case 'P':
- if (promptset) {
- freezedisp(0);
- #ifdef notdef
- if (column != 0) {
- ttyoutc('\r');
- ttyoutc('\n');
- }
- for (column = 0 ; prompt[column] ; column++)
- ttyoutc(prompt[column]);
- bcopy(prompt, outline, column);
- #endif
- }
- dispoff(savecol);
- q = strparam;
- i = 0;
- while (*q >= '0' && *q <= '9') {
- i = 10 * i + *q - '0';
- q++;
- }
- if (*q == ';')
- q++;
- promptcode = i;
- if (strlen(q) > COLUMNS - 1)
- q[COLUMNS - 1] = '\0';
- strcpy(prompt, q);
- promptset = 1;
- break;
- case 'D':
- promptset = 0;
- break;
- case 'I':
- insertchars(strparam, strlen(strparam));
- break;
- }
- savep = p;
- outstate = 0;
- goto state0;
- }
- if (outstate < 3 && savep != p) {
- dispoff(savecol);
- outreal(savep, p - savep);
- }
- }
- EOF
- if test `wc -c < output.c` -ne 4576
- then echo 'output.c is the wrong size'
- fi
- echo extracting update.c
- cat > update.c <<\EOF
- /*
- * Update the display of the line being edited on the screen.
- * Copyright (C) 1989 by Kenneth Almquist.
- */
-
-
- #include "attyed.h"
- #include "ed.h"
- #include <ctype.h>
-
- #ifndef NULL
- #define NULL 0
- #endif
-
-
- struct displine {
- char *text; /* text of line */
- int len; /* length of line */
- };
-
-
- int scrnwidth; /* width of screen */
- int eddisplay; /* if nonzero, editor display is valid */
- int needbeep; /* if nonzero, beep on next refresh */
- struct displine virtscrn[60]; /* what the screen should look like */
- struct displine realscrn[60]; /* what the screen does look like */
- int vslines; /* number of lines on virtual screen */
- int rslines; /* number of lines on real screen */
- int virtline; /* cursor position in virtscrn */
- int virtcol; /* cursor position in virtscrn */
- char *virtptr; /* &virtscrn[virtline].text[virtcol] */
- int *virtlen; /* &virtscrn[virtline].len */
- int realline; /* position of cursor on real screen */
- int realcol; /* position of cursor on real screen */
- int lastrealline; /* last real line on the screen */
- int startline; /* end of prompt */
- int startcol; /* end of prompt */
- char tcspace[120]; /* strings from termcap are stored here */
- int tc_am; /* cursor wraps around at right of screen */
- char *tc_bc; /* backspace */
- char *tc_bl; /* bell */
- int tc_bs; /* if set, terminal can backspace */
- char *tc_ce; /* clear to end of line */
- int tc_co; /* default width of screen */
- char *tc_do; /* cursor down one line */
- char *tc_nc; /* cursor right on column */
- char *tc_up; /* cursor up one line */
- int tc_xn; /* a newline is ignored after wrap around */
- char PC; /* pad character (for termcap routines) */
- extern int errno;
-
-
- #ifdef __STDC__
- void virtgoto(int, int);
- void drawch(int);
- void realgoto(int, int);
- void copytoreal(int, int);
- void allocline(struct displine *);
- #else
- void virtgoto();
- void drawch();
- void realgoto();
- void copytoreal();
- void allocline();
- #endif
-
- #ifdef __STDC__
- void ttyoutc(int);
- char *getenv(char *);
- int tgetent(char *, char *);
- int tgetnum(char *);
- int tgetflag(char *);
- char *tgetstr(char *, char **);
- void tputs(char *, int, void (*)(int));
- char *malloc(unsigned);
- #else
- void ttyoutc();
- char *getenv();
- int tgetent();
- int tgetnum();
- int tgetflag();
- char *tgetstr();
- void tputs();
- char *malloc();
- #endif
-
-
-
- /*
- * Read the termcap entry for this terminal.
- */
-
- void
- gettermcap() {
- char *termtype;
- char buffer[1024];
- char *tcp = tcspace;
- char *tc_pc;
-
- errno = 0;
- if ((termtype = getenv("TERM")) == NULL)
- badinit("$TERM not set");
- if (tgetent(buffer, termtype) <= 0)
- badinit("Termcap entry not found");
- tc_am = tgetflag("am");
- tc_bs = tgetflag("bs");
- tc_bc = tgetstr("bc", &tcp);
- tc_bl = tgetstr("bl", &tcp);
- tc_ce = tgetstr("ce", &tcp);
- tc_co = tgetnum("co");
- tc_do = tgetstr("do", &tcp);
- tc_nc = tgetstr("nc", &tcp);
- tc_pc = tgetstr("pc", &tcp);
- tc_up = tgetstr("up", &tcp);
- tc_xn = tgetflag("xn");
- PC = (tc_pc != NULL)? *tc_pc : '\0';
- if (tc_up == NULL)
- badinit("Atty can only run a terminal with a cursor-up escape sequence");
- scrnwidth = tc_co;
- }
-
-
-
- void
- newscrnwidth(width) {
- struct displine *lp;
- int disp = eddisplay;
-
- if (width <= 1)
- width = tc_co;
- if (width == scrnwidth)
- return;
- if (disp)
- dispoff(column);
- for (lp = virtscrn ; lp->text ; lp++) {
- free(lp->text);
- lp->text = NULL;
- }
- vslines = 0;
- for (lp = realscrn ; lp->text ; lp++) {
- free(lp->text);
- lp->text = NULL;
- }
- scrnwidth = width;
- if (disp)
- refresh();
- }
-
-
-
- void
- refresh() {
- struct displine *lp;
- char *p;
- int pointline, pointcol;
-
- if (eddisplay == 0) {
- if (realscrn[0].text == NULL)
- allocline(&realscrn[0]);
- if (virtscrn[0].text == NULL)
- allocline(&virtscrn[0]);
- for (lp = realscrn ; lp->text != NULL ; lp++)
- lp->len = 0;
- startcol = column % scrnwidth;
- startline = 0;
- realcol = startcol;
- realline = 0;
- if (column != 0) {
- bcopy(outline, realscrn[0].text, realcol);
- realscrn[0].len = realcol;
- bcopy(outline, virtscrn[0].text, realcol);
- virtscrn[0].len = realcol;
- if (promptset) {
- startcol = 0;
- startline = 1;
- }
- }
- if (promptset) {
- virtgoto(startline, startcol);
- for (p = prompt ; *p ; p++)
- drawch(*p);
- startline = virtline;
- startcol = virtcol;
- }
- lastrealline = 0;
- eddisplay = 1;
- }
- /* erase everything following the prompt from the virtual screen */
- virtgoto(startline, startcol);
- lp = &virtscrn[startline];
- lp->len = startcol;
- while ((++lp)->text != NULL)
- lp->len = 0;
- if (editprompt)
- drawch(editprompt);
- pointcol = -1;
- if (ttymode.echo) {
- for (p = curline ; p < endcurline ; p++) {
- if (p == point) {
- pointline = virtline;
- pointcol = virtcol;
- }
- drawch(*p);
- }
- }
- if (pointcol < 0) {
- pointline = virtline;
- pointcol = virtcol;
- }
- copytoreal(pointline, pointcol);
- }
-
-
- /*
- * Copy the virtual screen to the real screen.
- */
-
- void
- copytoreal(pointline, pointcol) {
- char *p;
- char *r;
- int line;
- int len;
- int limit;
- int col;
-
- for (line = 0 ; line <= virtline ; line++) {
- len = virtscrn[line].len;
- p = virtscrn[line].text;
- limit = realscrn[line].len;
- r = realscrn[line].text;
- if (r == NULL) {
- allocline(&realscrn[line]);
- r = realscrn[line].text;
- }
- if (limit > len)
- limit = len;
- for (col = 0 ; col < limit ; col++) {
- if (*p != *r) {
- if (realline != line || realcol != col)
- realgoto(line, col);
- ttyoutc(*p);
- realcol++;
- *r = *p;
- }
- p++;
- r++;
- }
- for ( ; col < len ; col++) {
- if (*p != ' ') {
- if (realline != line || realcol != col)
- realgoto(line, col);
- ttyoutc(*p);
- realcol++;
- }
- *r++ = *p++;
- }
- limit = realscrn[line].len;
- if (col < limit) {
- if (tc_ce == NULL || limit - col == 1) {
- for ( ; col < limit ; col++) {
- if (*r++ != ' ') {
- if (realline != line || realcol != col)
- realgoto(line, col);
- ttyoutc(' ');
- realcol++;
- }
- }
- } else {
- realgoto(line, col);
- tputs(tc_ce, 1, ttyoutc);
- }
- }
- if (realcol >= scrnwidth) {
- if (tc_xn || ! tc_am)
- outreal("\r\n", 2);
- realcol = 0;
- realline++;
- }
- realscrn[line].len = virtscrn[line].len;
- }
- while (line <= lastrealline) {
- if (realscrn[line].len > 0) {
- if (tc_ce) {
- realgoto(line, 0);
- tputs(tc_ce, 1, ttyoutc);
- } else {
- r = realscrn[line].text;
- limit = realscrn[line].len;
- for (col = 0 ; col < limit ; col++) {
- if (*r++ != ' ') {
- if (realline != line || realcol != col)
- realgoto(line, col);
- ttyoutc(' ');
- realcol++;
- }
- }
- if (realcol >= scrnwidth) {
- if (tc_xn || ! tc_am)
- outreal("\r\n", 2);
- realcol = 0;
- realline++;
- }
- }
- realscrn[line].len = 0;
- }
- line++;
- }
- realgoto(pointline, pointcol);
- if (needbeep) {
- if (tc_bl)
- tputs(tc_bl, 1, ttyoutc);
- needbeep = 0;
- }
- lastrealline = virtline;
- }
-
-
-
- /*
- * Move to beyond the end of the edited stuff, and turn the display off.
- */
-
- void
- movetoend() {
- realgoto(lastrealline, 0);
- ttyoutc('\n');
- eddisplay = 0;
- column = 0;
- promptset = 0;
- }
-
-
- /*
- * Output the line being edited to the display, and freeze it there.
- * If the data flag is zero, only freeze the prompt.
- */
-
- void
- freezedisp(data) {
- int i;
- struct displine *lp;
- int save_echo;
-
- save_echo = ttymode.echo;
- ttymode.echo = data;
- refresh();
- ttymode.echo = save_echo;
- eddisplay = 0;
- column = realcol;
- lp = &realscrn[realline];
- for (i = 0 ; i < column ; i++) {
- outline[i] = (i < lp->len)? lp->text[i] : ' ';
- }
- promptset = 0;
- }
-
-
-
- /*
- * Turn display off.
- */
-
- void
- dispoff(col) {
- int line;
-
- if (eddisplay == 0)
- return;
- col = col % scrnwidth;
- virtscrn[0].len = col;
- for (line = 1 ; line <= lastrealline ; line++)
- virtscrn[line].len = 0;
- copytoreal(0, col);
- eddisplay = 0;
- }
-
-
-
- void
- virtgoto(line, col) {
- struct displine *lp;
- char *p;
-
- while (vslines <= line) {
- allocline(&virtscrn[vslines]);
- vslines++;
- }
- lp = &virtscrn[line];
- if (lp->len < col) {
- p = &lp->text[lp->len];
- do *p++ = ' ';
- while (++lp->len < col);
- }
- virtline = line;
- virtcol = col;
- virtptr = &lp->text[col];
- virtlen = &lp->len;
- }
-
-
- void
- drawch(c)
- char c;
- {
- if (! isprint(c)) {
- if (c == '\t') {
- do drawch(' ');
- while ((virtcol & 07) != 0);
- return;
- } else {
- drawch('^');
- c ^= 0100;
- }
- }
- *virtptr++ = c;
- virtcol++;
- if (*virtlen < virtcol)
- *virtlen = virtcol;
- if (virtcol >= scrnwidth) {
- virtgoto(virtline + 1, 0);
- }
- }
-
-
- /*
- * Goto the specified location on the real screen. Note that we may
- * scroll the screen, so we must use line feed rather than do for
- * downward motion.
- */
-
- void
- realgoto(line, col) {
- char *text;
- int len;
-
- while (realline > 0 && realline > line) {
- tputs(tc_up, 1, ttyoutc);
- realline--;
- }
- while (realline < line) {
- #ifdef notdef
- tputs(tc_do, 1, ttyoutc);
- #else
- ttyoutc('\n');
- #endif
- realline++;
- }
- if (col < realcol - col) {
- ttyoutc('\r');
- realcol = 0;
- }
- if (realcol > col) {
- if (tc_bc) {
- do {
- tputs(tc_bc, 1, ttyoutc);
- } while (--realcol > col);
- } else {
- do {
- ttyoutc('\b');
- } while (--realcol > col);
- }
- }
- if (realcol < col) {
- text = realscrn[realline].text;
- len = realscrn[realline].len;
- do {
- ttyoutc(realcol < len? text[realcol] : ' ');
- } while (++realcol < col);
- }
- if (line == 0 && realline > 0) {
- tputs(tc_up, 1, ttyoutc);
- realline--;
- }
- }
-
-
-
- void
- allocline(lp)
- struct displine *lp;
- {
- char *p;
-
- if (lp->text != NULL)
- return;
- if ((p = malloc(scrnwidth)) == NULL)
- fatal("Malloc line failed");
- lp->text = p;
- lp->len = 0;
- }
- EOF
- if test `wc -c < update.c` -ne 10496
- then echo 'update.c is the wrong size'
- fi
- echo extracting vi.bind
- cat > vi.bind <<\EOF
- # A very half-hearted attempt at a vi mode.
-
- mode 0
- default self-insert
- b ^H delete-backward-char
- b ^J newline-and-insert
- b \r newline
- b ^V quoted-insert
- b ^W backward-kill-word
- b ^X kill-input
- b ^Z tty-susp
- b ^[ mode-1
- b \034 tty-quit
- b \037 end-of-file
- b \177 tty-intr
-
- mode 1
- default undefined
- b ^H backward-char
- b ^J newline-and-insert
- b \r newline
- b ^Z tty-susp
- b \034 tty-quit
- b \037 end-of-file
- b \s forward-char
- b + next-history
- b - previous-history
- b 0 digit-argument
- b 1 digit-argument
- b 2 digit-argument
- b 3 digit-argument
- b 4 digit-argument
- b 5 digit-argument
- b 6 digit-argument
- b 7 digit-argument
- b 8 digit-argument
- b 9 digit-argument
- b / re-search-forward
- b ? re-search-backward
- b B backward-word
- b W forward-word
- b a mode-0
- b b backward-word
- b e forward-word
- b h backward-char
- b i mode-0
- b j previous-history
- b k next-history
- b l forward-char
- b w forward-word
- b x delete-backward-char
- b \177 tty-intr
-
- b db backward-kill-word
- b dd kill-input
- b dw kill-word
- EOF
- if test `wc -c < vi.bind` -ne 974
- then echo 'vi.bind is the wrong size'
- fi
- echo extracting regex.h
- cat > regex.h <<\EOF
- /* Definitions for data structures callers pass the regex library.
- Copyright (C) 1985 Free Software Foundation, Inc.
-
- NO WARRANTY
-
- BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
- NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT
- WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
- RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
- WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
- BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY
- AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
- DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
- CORRECTION.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
- STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
- WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
- LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
- OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
- USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
- DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
- A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
- PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
- DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
-
- GENERAL PUBLIC LICENSE TO COPY
-
- 1. You may copy and distribute verbatim copies of this source file
- as you receive it, in any medium, provided that you conspicuously and
- appropriately publish on each copy a valid copyright notice "Copyright
- (C) 1985 Free Software Foundation, Inc."; and include following the
- copyright notice a verbatim copy of the above disclaimer of warranty
- and of this License. You may charge a distribution fee for the
- physical act of transferring a copy.
-
- 2. You may modify your copy or copies of this source file or
- any portion of it, and copy and distribute such modifications under
- the terms of Paragraph 1 above, provided that you also do the following:
-
- a) cause the modified files to carry prominent notices stating
- that you changed the files and the date of any change; and
-
- b) cause the whole of any work that you distribute or publish,
- that in whole or in part contains or is a derivative of this
- program or any part thereof, to be licensed at no charge to all
- third parties on terms identical to those contained in this
- License Agreement (except that you may choose to grant more extensive
- warranty protection to some or all third parties, at your option).
-
- c) You may charge a distribution fee for the physical act of
- transferring a copy, and you may at your option offer warranty
- protection in exchange for a fee.
-
- Mere aggregation of another unrelated program with this program (or its
- derivative) on a volume of a storage or distribution medium does not bring
- the other program under the scope of these terms.
-
- 3. You may copy and distribute this program (or a portion or derivative
- of it, under Paragraph 2) in object code or executable form under the terms
- of Paragraphs 1 and 2 above provided that you also do one of the following:
-
- a) accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of
- Paragraphs 1 and 2 above; or,
-
- b) accompany it with a written offer, valid for at least three
- years, to give any third party free (except for a nominal
- shipping charge) a complete machine-readable copy of the
- corresponding source code, to be distributed under the terms of
- Paragraphs 1 and 2 above; or,
-
- c) accompany it with the information you received as to where the
- corresponding source code may be obtained. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form alone.)
-
- For an executable file, complete source code means all the source code for
- all modules it contains; but, as a special exception, it need not include
- source code for modules which are standard libraries that accompany the
- operating system on which the executable file runs.
-
- 4. You may not copy, sublicense, distribute or transfer this program
- except as expressly provided under this License Agreement. Any attempt
- otherwise to copy, sublicense, distribute or transfer this program is void and
- your rights to use the program under this License agreement shall be
- automatically terminated. However, parties who have received computer
- software programs from you with this License Agreement will not have
- their licenses terminated so long as such parties remain in full compliance.
-
- 5. If you wish to incorporate parts of this program into other free
- programs whose distribution conditions are different, write to the Free
- Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not yet
- worked out a simple rule that can be stated here, but we will often permit
- this. We will be guided by the two goals of preserving the free status of
- all derivatives of our free software and of promoting the sharing and reuse of
- software.
-
-
- In other words, you are welcome to use, share and improve this program.
- You are forbidden to forbid anyone else to use, share and improve
- what you give them. Help stamp out software-hoarding! */
-
-
- #ifndef RE_NREGS
- #define RE_NREGS 10
- #endif
-
- /* This data structure is used to represent a compiled pattern. */
-
- struct re_pattern_buffer
- {
- char *buffer; /* Space holding the compiled pattern commands. */
- int allocated; /* Size of space that buffer points to */
- int used; /* Length of portion of buffer actually occupied */
- char *fastmap; /* Pointer to fastmap, if any, or zero if none. */
- /* re_search uses the fastmap, if there is one,
- to skip quickly over totally implausible characters */
- char *translate; /* Translate table to apply to all characters before comparing.
- Or zero for no translation.
- The translation is applied to a pattern when it is compiled
- and to data when it is matched. */
- char fastmap_accurate;
- /* Set to zero when a new pattern is stored,
- set to one when the fastmap is updated from it. */
- char can_be_null; /* Set to one by compiling fastmap
- if this pattern might match the null string.
- It does not necessarily match the null string
- in that case, but if this is zero, it cannot.
- 2 as value means can match null string
- but at end of range or before a character
- listed in the fastmap. */
- };
-
- /* Structure to store "register" contents data in.
-
- Pass the address of such a structure as an argument to re_match, etc.,
- if you want this information back.
-
- start[i] and end[i] record the string matched by \( ... \) grouping i,
- for i from 1 to RE_NREGS - 1.
- start[0] and end[0] record the entire string matched. */
-
- struct re_registers
- {
- int start[RE_NREGS];
- int end[RE_NREGS];
- };
-
- /* These are the command codes that appear in compiled regular expressions, one per byte.
- Some command codes are followed by argument bytes.
- A command code can specify any interpretation whatever for its arguments.
- Zero-bytes may appear in the compiled regular expression. */
-
- enum regexpcode
- {
- unused,
- exactn, /* followed by one byte giving n, and then by n literal bytes */
- begline, /* fails unless at beginning of line */
- endline, /* fails unless at end of line */
- jump, /* followed by two bytes giving relative address to jump to */
- on_failure_jump, /* followed by two bytes giving relative address of place
- to resume at in case of failure. */
- finalize_jump, /* Throw away latest failure point and then jump to address. */
- maybe_finalize_jump, /* Like jump but finalize if safe to do so.
- This is used to jump back to the beginning
- of a repeat. If the command that follows
- this jump is clearly incompatible with the
- one at the beginning of the repeat, such that
- we can be sure that there is no use backtracking
- out of repetitions already completed,
- then we finalize. */
- dummy_failure_jump, /* jump, and push a dummy failure point.
- This failure point will be thrown away
- if an attempt is made to use it for a failure.
- A + construct makes this before the first repeat. */
- anychar, /* matches any one character */
- charset, /* matches any one char belonging to specified set.
- First following byte is # bitmap bytes.
- Then come bytes for a bit-map saying which chars are in.
- Bits in each byte are ordered low-bit-first.
- A character is in the set if its bit is 1.
- A character too large to have a bit in the map
- is automatically not in the set */
- charset_not, /* similar but match any character that is NOT one of those specified */
- start_memory, /* starts remembering the text that is matched
- and stores it in a memory register.
- followed by one byte containing the register number.
- Register numbers must be in the range 0 through NREGS. */
- stop_memory, /* stops remembering the text that is matched
- and stores it in a memory register.
- followed by one byte containing the register number.
- Register numbers must be in the range 0 through NREGS. */
- duplicate, /* match a duplicate of something remembered.
- Followed by one byte containing the index of the memory register. */
- before_dot, /* Succeeds if before dot */
- at_dot, /* Succeeds if at dot */
- after_dot, /* Succeeds if after dot */
- begbuf, /* Succeeds if at beginning of buffer */
- endbuf, /* Succeeds if at end of buffer */
- wordchar, /* Matches any word-constituent character */
- notwordchar, /* Matches any char that is not a word-constituent */
- wordbeg, /* Succeeds if at word beginning */
- wordend, /* Succeeds if at word end */
- wordbound, /* Succeeds if at a word boundary */
- notwordbound, /* Succeeds if not at a word boundary */
- syntaxspec, /* Matches any character whose syntax is specified.
- followed by a byte which contains a syntax code, Sword or such like */
- notsyntaxspec /* Matches any character whose syntax differs from the specified. */
- };
-
- extern char *re_compile_pattern ();
- /* Is this really advertised? */
- extern void re_compile_fastmap ();
- extern int re_search (), re_search_2 ();
- extern int re_match (), re_match_2 ();
-
- /* 4.2 bsd compatibility (yuck) */
- extern char *re_comp ();
- extern int re_exec ();
-
- #ifdef SYNTAX_TABLE
- extern char *re_syntax_table;
- #endif
- EOF
- if test `wc -c < regex.h` -ne 10736
- then echo 'regex.h is the wrong size'
- fi
- echo Archive 3 unpacked
- exit
-
-